//package com.whosly.disclosure.early.handler.autoconfig.autoconfigure;
//
//import cn.hutool.core.annotation.AnnotationUtil;
//import cn.hutool.core.date.DateUtil;
//import cn.hutool.core.date.SystemClock;
//import cn.hutool.core.util.DesensitizedUtil;
//import cn.hutool.core.util.StrUtil;
//import com.whosly.api.autoconfigure.context.SpringContextAwareHolder;
//import com.whosly.api.autoconfigure.holder.AnnotationMapsHolder;
//import com.whosly.disclosure.early.handler.autoconfig.api.IActionService;
//import com.whosly.disclosure.early.handler.autoconfig.data.ActionData;
//import com.whosly.disclosure.early.handler.autoconfig.data.ActionHandlerType;
//import com.whosly.disclosure.early.handler.autoconfig.data.DisclosureConfigData;
//import com.whosly.disclosure.early.handler.autoconfig.util.IpUtil;
//import com.whosly.disclosure.early.handler.autoconfig.registrar.DisclosureEarlyConfigRegistrar;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang3.ArrayUtils;
//import org.apache.commons.lang3.StringUtils;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.reflect.MethodSignature;
//import org.slf4j.event.Level;
//import org.springframework.beans.factory.InitializingBean;
//import org.springframework.stereotype.Controller;
//import org.springframework.web.bind.annotation.RestController;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//
//import javax.servlet.http.HttpServletRequest;
//import java.lang.reflect.Method;
//import java.util.*;
//
//@Aspect
//@Slf4j
//public class RActionAspect implements InitializingBean {
//    private DisclosureConfigData configData;
//
//    private IActionService actionService;
//
//    /**
//     * 敏感字段，需进行脱敏处理
//     */
//    private static final String[] KEYS = {
//            // 手机号码
//            "phone",
//            // 身份证号码
//            "cert", "idNumber",
//            // 地址
//            "address",
//            // 各种code
//            "code", "token"
//            // just for test
//            };
//    /**
//     * 敏感字段，需进行脱敏处理
//     */
//    private static final Set<String> KEY_LIST = new HashSet<>();
//    static {
//        KEY_LIST.addAll(Arrays.asList(KEYS));
//    }
//
//    public RActionAspect() {
//        AnnotationMapsHolder<DisclosureConfigData> holder = AnnotationMapsHolder.INSTANCE(DisclosureEarlyConfigRegistrar.BEAN_NAME);
//        DisclosureConfigData configData = holder.get();
//
//        this.configData = configData;
//    }
//
//    public RActionAspect(DisclosureConfigData configData) {
//        this.configData = configData;
//    }
//
//    // Around --> Before --> Around --> After --> AfterReturning --> AfterThrowing
//    @Around("@annotation(methodAction)")
//    public Object controllerLogPointCutAround(ProceedingJoinPoint joinPoint, RMethodAction methodAction) throws Throwable {
//        Long innerStart = SystemClock.now();
//
//        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//
//        // 拦截类
//        Class<?> clazz = joinPoint.getTarget().getClass();
//        String className = clazz.getName();
//        // 拦截类的方法
//        Method method = signature.getMethod();
//        String methodName = method.getName();
//
//        String target = className + "." + methodName;
//
//        Map parameters = getMethodParams(joinPoint, signature);
//
//        Long methodStart = SystemClock.now();
//        Object result = null;
//        try{
//            result = joinPoint.proceed();
//        } catch (Exception e){
//            log(Level.WARN, "proceed error:{}.", e.getMessage());
//
//            throw e;
//        } finally {
//            process(methodAction, clazz, className, methodName, target, parameters, innerStart, methodStart, result);
//        }
//
//        return result;
//    }
//
//    @Override
//    public void afterPropertiesSet() throws Exception {
//        log.info("RActionAspect afterPropertiesSet finish.");
//
//        IActionService as = SpringContextAwareHolder.get(IActionService.class);
//
//        this.actionService = as;
//    }
//
//    private void process(RMethodAction methodAction, Class<?> clazz, String className, String methodName, String target,
//                         Map parameters, Long innerStart, Long methodStart, Object result){
//        Long methodEnd = SystemClock.now();
//
//        // 默认为方法级
//        ActionHandlerType actionHandlerType = null;
//        String realIp = "";
//        ActionData.Web web = new ActionData.Web();
//        try{
//            realIp = IpUtil.getRealIp();
//
//            if(AnnotationUtil.hasAnnotation(clazz, RestController.class)
//                    || AnnotationUtil.hasAnnotation(clazz, Controller.class)){
//                //获取用户ip地址
//                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
//                        .getRequest();
//
//                if(request != null){
//                    String url = request.getRequestURI();
//                    String ip = request.getRemoteAddr();
//
//                    // 获取请求方式, GET 等
//                    String webMethod = request.getMethod();
//                    actionHandlerType = ActionHandlerType.of(webMethod);
//
//                    web.setPath(url);
//                    web.setClientIp(ip);
//                }
//            }
//        } catch (Exception ee){
//            // do nothing
////            log.warn("get HttpServletRequest error:{}.", ee.getMessage());
//        }
//
//        ActionData actionData = ActionData.builder()
//                .userId(actionService.getUserId())
//                .actionName(StringUtils.isNotEmpty(methodAction.name())
//                        ? methodAction.name() : className + "#" + methodName)
//                .actionClassName(className)
//                .actionMethodName(methodName)
//                .actionTime(DateUtil.now())
//                .parameters(parameters)
//                .timeMillis(SystemClock.now() - innerStart)
//                .timeMethodMillis(methodEnd - methodStart)
//                .serverIp(realIp)
//                .actionHandlerType(actionHandlerType != null ? actionHandlerType : ActionHandlerType.METHOD)
//                .web(web)
//                .build();
//        actionService.storage(actionData);
//    }
//
//    private static void log(Level level, String format, Object... arguments){
//        if(level == Level.INFO){
//            log.info(format, arguments);
//        } else if(level == Level.DEBUG){
//            log.debug(format, arguments);
//        } else if(level == Level.TRACE){
//            log.trace(format, arguments);
//        } else if(level == Level.WARN){
//            log.warn(format, arguments);
//        } else if(level == Level.ERROR){
//            log.error(format, arguments);
//        }
//    }
//
//    /**
//     *  获取请求方法的参数
//     */
//    private static Map<String, Object> getMethodParams(ProceedingJoinPoint joinPoint, MethodSignature signature){
//        Map<String, Object>  params = new HashMap();
//
////        Object[] parameters = joinPoint.getArgs();
////        String[] parameterNames = signature.getParameterNames();
//        try{
//            String[] names = signature.getParameterNames();
//            if (ArrayUtils.isEmpty(names)){
//                return params;
//            }
//
//            Object[] values = joinPoint.getArgs();
//            for (int i = 0; i < names.length; i++) {
//                String key = names[i];
//                Object value = values[i];
//
//                params.put(key, value);
//            }
//
//            // 敏感字段的脱敏
//            for (Map.Entry<String, Object> entry : params.entrySet()) {
//                if(KEY_LIST.contains(entry.getKey())){
//                    Object value = entry.getValue();
//
//                    // 值的替换
//                    if(value instanceof String){
//                        String val = (String) value;
//                        if(StringUtils.length(val) <= 4){
//                            // 少于等于2位的，不会加密
//                            params.put(entry.getKey(), StrUtil.hide(val, 1, val.length() - 1));
//                        }else if(StringUtils.length(val) <= 8){
//                            // 少于等于5位的，不会加密
//                            params.put(entry.getKey(), StrUtil.hide(val, 3, val.length() - 2));
//                        }else {
//                            params.put(entry.getKey(), DesensitizedUtil.idCardNum(val, 3, 4));
//                        }
//                    }else{
//                        // 暂未实现的脱敏部分
//                        //.
//                    }
//                }
//            }
//        }catch (Exception ex){
//            log(Level.WARN, "getMethodParams error:{}.", ex.getMessage());
//        }
//
//        return params;
//    }
//
//}
